home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FM Towns: Software Contest 3
/
FM Towns Software Contest 3.iso
/
exp
/
astral
/
a1
/
game
/
source
/
wire3d_a.asm
< prev
next >
Wrap
Assembly Source File
|
1994-01-07
|
9KB
|
681 lines
;============================================================================
;
; Wireflame アセンブラ版
;
;============================================================================
.386p
;--- 各種宣言
extrn sin_data:dword,cos_data:dword,line:near
public wire3d
arg_angle equ ss:[ebp]+4+4
arg_offset equ ss:[ebp]+4+8
arg_obj equ ss:[ebp]+4+12
arg_page equ ss:[ebp]+4+16
sight_angle equ 100h
wire_object struc
color dd ?
dummy dd ?
point_num dd ?
point dd 128*3 dup(?)
line_num dd ?
m_line dd 128*2 dup(?)
wire_object ends
call_line macro
; push eax
; push ecx
; push edx
push arg_page
mov eax,arg_obj
push [eax].color
push y2
push x2
push y1
push x1
call line
add esp,6*4
; pop edx
; pop ecx
; pop eax
endm
break_point macro reg
mov eax,reg
jmp exit
endm
DSEG segment dword 'DATA'
assume cs:CSEG,ds:DSEG
;--- プログラム用ワークエリア
align 4
i dd ? ;i
point_work dd 192 dup(?) ;point_work[192]
x1 dd 0 ;x1,y1,x2,y2
y1 dd 0
x2 dd 255
y2 dd 255
clip_work2 dd ? ;w
xx dd ? ;xx
yy dd ? ;yy
point_w dd 12 dup(?) ;point_w[4][3]([y][x*4]+point_w)
z_w dd ? ;z_w
pass dd 192 dup(?) ;pass[192]
DSEG ends
CSEG segment dword 'CODE'
assume cs:CSEG,ds:DSEG
;----------------------------------------------------------------------------
; void wire3d(unsigned char *angle,int *offset,WIRE_OBJECT *obj,int pag
; e);
;----------------------------------------------------------------------------
db 'wire3d',6
align 4
wire3d proc near
push ebp
mov ebp,esp
push edi
push esi
push ebx
mov edi,arg_obj ;edi=obj
;--- 回転,オフセット付加,透視変換
mov eax,[edi].point_num ;ループカウンタをセット
lea ebx,[eax+eax*2] ;ebx=Loop Counter
align 4
roll_loop:
sub ebx,3 ;ebx-=3
;--- Y軸の回転
mov eax,arg_angle
mov ecx,0
mov cl,ds:[eax]+1
; point_w[2][0]=(point_w[1][0] * cos_data[angle[1]] -
; point_w[1][2] * sin_data[angle[1]])>>16;
mov eax,ds:[edi].point[ebx*4]+0
imul eax,ds:cos_data[ecx*4]
mov edx,ds:[edi].point[ebx*4]+8
imul edx,ds:sin_data[ecx*4]
sub eax,edx
sar eax,7
mov point_w+1*12+0,eax
; point_w[2][2]=(point_w[1][0] * sin_data[angle[1]] +
; point_w[1][2] * cos_data[angle[1]])>>16;
mov eax,ds:[edi].point[ebx*4]+0
imul eax,ds:sin_data[ecx*4]
mov edx,ds:[edi].point[ebx*4]+8
imul edx,ds:cos_data[ecx*4]
add eax,edx
sar eax,7
mov point_w+1*12+8,eax
;--- X軸の回転
mov eax,arg_angle ;ecxにangle[0]を入れる
mov ecx,0
mov cl,ds:[eax]
; point_w[1][1]=( obj->point[i+1] * cos_data[angle[0]] +
; obj->point[i+2] * sin_data[angle[0]] )>>16;
mov eax,ds:[edi].point[ebx*4]+4
imul eax,ds:cos_data[ecx*4]
mov edx,point_w+12*1+8
imul edx,ds:sin_data[ecx*4]
add eax,edx
sar eax,7
mov point_w+2*12+4,eax
; point_w[1][2]=(-obj->point[i+1] * sin_data[angle[0]] +
; obj->point[i+2] * cos_data[angle[0]] )>>16;
mov eax,ds:[edi].point[ebx*4]+4
imul eax,ds:sin_data[ecx*4]
mov edx,point_w+12*1+8
imul edx,ds:cos_data[ecx*4]
sub edx,eax
sar edx,7
mov eax,arg_offset
add edx,ds:[eax]+8
mov point_w+3*12+8,edx
;--- Z軸の回転
mov eax,arg_angle
mov ecx,0
mov cl,ds:[eax]+2
; point_w[3][0]=(( point_w[2][0] * cos_data[angle[2]] +
; point_w[2][1] * sin_data[angle[2]])>>16)+offset[0];
mov eax,point_w+1*12+0
imul eax,cos_data[ecx*4]
mov edx,point_w+2*12+4
imul edx,sin_data[ecx*4]
add eax,edx
sar eax,7
mov edx,arg_offset
add eax,ds:[edx]+0
mov point_w+3*12+0,eax
; point_w[3][1]=((-point_w[2][0] * sin_data[angle[2]] +
; point_w[2][1] * cos_data[angle[2]])>>16)+offset[1];
mov eax,point_w+1*12+0
imul eax,sin_data[ecx*4]
mov edx,point_w+2*12+4
imul edx,cos_data[ecx*4]
sub edx,eax
sar edx,7
mov eax,arg_offset
add edx,ds:[eax]+4
mov point_w+3*12+4,edx
;--- 透視変換
; z_w=point_w[3][2]*SIGHT_ANGLE+0x10000;
mov eax,point_w+3*12+8
add eax,100h
mov ecx,eax
; if(z_w<=0){
; pass[i]=1;
; continue;
; }
cmp ecx,0
jnle roll_next1
mov pass[ebx*4],1
cmp ebx,0
jnz roll_loop
jmp roll_loop_break
; point_work[i+0]=((point_w[3][0]<<16)/z_w)+128;
align 4
roll_next1:
mov pass[ebx*4],0
mov eax,point_w+3*12+0
sal eax,8
cdq
idiv ecx
add eax,128
mov point_work[ebx*4]+0,eax
; point_work[i+1]=((point_w[3][1]<<16)/z_w)+128;
mov eax,point_w+3*12+4
neg eax
sal eax,8
cdq
idiv ecx
add eax,120
mov point_work[ebx*4]+4,eax
;--- ループおしまい
roll_loop_end:
cmp ebx,0
jnz roll_loop
roll_loop_break:
;--- クリッピング,描画
mov eax,[edi].line_num
lea ebx,[eax*2]
align 4
draw_loop:
sub ebx,2
mov edi,arg_obj
; if(pass[obj->line[i]*3]==1 || pass[obj->line[i+1]*3]==1)continue;
; x1=point_work[obj->line[i]*3];
mov eax,ds:[edi].m_line[ebx*4] ;obj->line[i]
lea edx,[eax+eax*2] ;*3
cmp pass[edx*4],1
jz continue
mov eax,point_work[edx*4]
mov x1,eax
; y1=point_work[obj->line[i]*3+1];
mov eax,point_work[edx*4]+4 ;+1
mov y1,eax
; x2=point_work[obj->line[i+1]*3];
mov eax,ds:[edi].m_line[ebx*4]+4
lea edx,[eax+eax*2]
cmp pass[edx*4],1
jz continue
mov eax,point_work[edx*4]
mov x2,eax
; y2=point_work[obj->line[i+1]*3+1];
mov eax,point_work[edx*4]+4
mov y2,eax
; if(x1>0 && x1<255 && y1>0 && y1<255 &&
; x2>0 && x2<255 && y2>0 && y2<255){
; line(x1,y1,x2,y2,obj->color,page);
; continue;
; }
mov eax,x1
or eax,y1
or eax,x2
or eax,y2
and eax,0ffffff00h
jnz next1
call_line
cmp ebx,0
jnz draw_loop
jmp draw_loop_break
align 4
next1:
; jmp continue
; if( (x1<0 && x2<0) || (x1>255 && x2>255) ||
; (y1<0 && y2<0) || (y1>255 && y2>255) ){
; continue;
; }
mov eax,x1
and eax,x2
and eax,80000000h
jnz continue
cmp x1,256
jb next2
cmp x2,256
jnb continue
align 4
next2:
mov eax,y1
and eax,y2
and eax,80000000h
jnz continue
cmp y1,256
jb next3
cmp y2,256
jnb continue
align 4
next3:
; xx..ecx
; yy..esi
; if(x2<0){
; xx=1;
; }
mov ecx,x2
cmp ecx,80000000h
jb next4
mov ecx,1
jmp next5
; else{
; if(x2>255){
; xx=255;
; }
; else{
; xx=x2;
; }
; }
align 4
next4:
cmp ecx,256
jb next5
mov ecx,255
align 4
next5:
; if(x2==x1){
; yy=y2;
; }
mov eax,x1
cmp eax,x2
jnz next6
mov esi,y2
jmp next7
; else{
; yy=y2-(y2-y1)*(x2-xx)/(x2-x1);
; }
align 4
next6:
mov eax,y2
sub eax,y1
mov edi,x2
sub edi,ecx
imul eax,edi
cdq
mov edi,x2
sub edi,x1
idiv edi
mov edi,y2
sub edi,eax
mov esi,edi
align 4
next7:
; if(yy<0){
; yy=0;
; }
cmp esi,80000000h
jb next8
mov esi,0
jmp next9
align 4
next8:
; else{
; if(yy>255){
; yy=255;
; }
; else{
; goto EXIT1;
; }
; }
cmp esi,256
jb EXIT_clip1
mov esi,255
align 4
next9:
; if(y2==y1){
; xx=x2;
; }
; else{
; xx=x2-(x2-x1)*(y2-yy)/(y2-y1);
; }
mov eax,y1
cmp eax,y2
jnz next10
mov ecx,x2
jmp EXIT_clip1
align 4
next10:
mov eax,x2
sub eax,x1
mov edi,y2
sub edi,esi
imul eax,edi
cdq
mov edi,y2
sub edi,y1
idiv edi
mov edi,x2
sub edi,eax
mov ecx,edi
align 4
EXIT_clip1:
; EXIT1:
; x2=xx;
; y2=yy;
mov x2,ecx
mov y2,esi
; swap x1,x2;
; swap y1,y2;
mov eax,x1
mov edx,x2
mov x2,eax
mov x1,edx
mov eax,y1
mov edx,y2
mov y2,eax
mov y1,edx
next23:
; xx..ecx
; yy..esi
; if(x2<0){
; xx=1;
; }
mov ecx,x2
cmp ecx,80000000h
jb next24
mov ecx,1
jmp next25
; else{
; if(x2>255){
; xx=255;
; }
; else{
; xx=x2;
; }
; }
align 4
next24:
cmp ecx,256
jb next25
mov ecx,255
align 4
next25:
; if(x2==x1){
; yy=y2;
; }
mov eax,x1
cmp eax,x2
jnz next26
mov esi,y2
jmp next27
; else{
; yy=y2-(y2-y1)*(x2-xx)/(x2-x1);
; }
align 4
next26:
mov eax,y2
sub eax,y1
mov edi,x2
sub edi,ecx
imul eax,edi
cdq
mov edi,x2
sub edi,x1
idiv edi
mov edi,y2
sub edi,eax
mov esi,edi
align 4
next27:
; if(yy<0){
; yy=0;
; }
cmp esi,80000000h
jb next28
mov esi,0
jmp next29
align 4
next28:
; else{
; if(yy>255){
; yy=255;
; }
; else{
; goto EXIT1;
; }
; }
cmp esi,256
jb EXIT_clip2
mov esi,255
align 4
next29:
; if(y2==y1){
; xx=x2;
; }
; else{
; xx=x2-(x2-x1)*(y2-yy)/(y2-y1);
; }
mov eax,y1
cmp eax,y2
jnz next210
mov ecx,x2
jmp EXIT_clip2
align 4
next210:
mov eax,x2
sub eax,x1
mov edi,y2
sub edi,esi
imul eax,edi
cdq
mov edi,y2
sub edi,y1
idiv edi
mov edi,x2
sub edi,eax
mov ecx,edi
align 4
EXIT_clip2:
; EXIT1:
; x2=xx;
; y2=yy;
mov x2,ecx
mov y2,esi
call_line
;--- ループおしまい
align 4
continue:
cmp ebx,0
jnz draw_loop
draw_loop_break:
;--- Return
exit:
pop ebx
pop esi
pop edi
pop ebp
ret
wire3d endp
CSEG ends
end